/****************************************************************************
 *
 *  ALi (Shanghai) Corporation, All Rights Reserved. 2007 Copyright (C)
 *
 *  File: pvr_mgr_api.c
 *
 *  Description: This file describes pvr manager layer output APIs.
 *
 *  History:
 *      Date        	Author      	Version  		Comment
 *      ====        	======      	=======  		=======
 *  1.  2009.3.20  		Dukula_Zhu  	0.0.1  		
 *
 ****************************************************************************/
#include "pvr_mgr_data.h"
#include <api/libsi/lib_epg.h>


/**************************** global params ***********************************/
ppvr_mgr_info g_pvr_mgr_info = NULL;

/**************************** static declare ***********************************/



/**************************** internal apis ***********************************/
BOOL _pvr_mgr_cmd_main(ppvr_mgr_cmd n_cmd)
{	
	INT8 direction, speed;
	BOOL ret = TRUE;
	
	UINT32 result = 0;
	UINT32 flag = n_cmd->flag;
	PVR_HANDLE handle = n_cmd->handle;
			
	PDEBUG("++++ NV CMD: 0x%X\n", n_cmd->cmd);
	PDEBUG("  param16 = 0x%x\n", n_cmd->param16);
	PDEBUG("  param32 = 0x%x\n", n_cmd->param32);
	PDEBUG("  param32_ext = 0x%x\n", n_cmd->param32_ext);
	PDEBUG("  handle  = 0x%x\n", n_cmd->handle);
	PDEBUG("  flag    = 0x%08x\n", n_cmd->flag);
	PDEBUG("  sync    = 0x%x\n", n_cmd->sync);
	
	switch(n_cmd->cmd) 
	{
		case PVR_MGR_REGISTER:
			_pvr_mgr_register_partition((struct pvr_register_info *)n_cmd->param32);
			if(n_cmd->sync == 0)
			{
				struct pvr_register_info *reg_info = (struct pvr_register_info *)n_cmd->param32;
				_pvr_mgr_free(reg_info);
			}
			
			break;
		case PVR_MGR_NOTICE:
			break;	
		case PVR_MGR_CLEANUP:
			_pvr_mgr_cleanup_all();
			break;
		case PVR_MGR_CLEANUP_DEVICE:
			_pvr_mgr_cleanup_device(n_cmd->param16);
			break;
		case PVR_MGR_CLEANUP_PARTITION:
			_pvr_mgr_cleanup_partition((struct pvr_clean_info *)n_cmd->param32);
			break;
		case PVR_MGR_COPY:
			break;
		default:
			PERROR("%s: %04x is unknown command!\n", __FUNCTION__, n_cmd->cmd);
			break;
	}

	//to set the return result!
	if(n_cmd->sync != 0)
	{
		*n_cmd->p_result = result;
		_pvr_mgr_declare_cmd_finish(flag);
	}
	
	PDEBUG("----- PVR MGR CMD: 0x%X done!\n", n_cmd->cmd);

	return ret;
}

RET_CODE pvr_mgr_attach(PPVR_MGR_CFG cfg, PPVR_CFG ini_param)
{
	RET_CODE ret = RET_SUCCESS;
	UINT16 i;

	if((cfg == NULL) || (ini_param == NULL))
		return RET_FAILURE;

	// param sanity check
	if (STRLEN(ini_param->info_file_name) == 0)
		STRCPY(ini_param->info_file_name, "info.dvr");

	if (STRLEN(ini_param->info_file_name_new) == 0)
		STRCPY(ini_param->info_file_name_new, "info3.dvr");

	if (STRLEN(ini_param->ts_file_format) == 0)
		STRCPY(ini_param->ts_file_format, "dvr");
	
	if (STRLEN(ini_param->ts_file_format_new) == 0)
		STRCPY(ini_param->ts_file_format_new, "ts");
	
	if (STRLEN(ini_param->ps_file_format) == 0)
		STRCPY(ini_param->ps_file_format, "mpg");

	if (STRLEN(ini_param->test_file1) == 0)
		STRCPY(ini_param->test_file1, "test_write1.dvr");
	
	if (STRLEN(ini_param->test_file2) == 0)
		STRCPY(ini_param->test_file2, "test_write2.dvr");

#if 1//def VMX_PVR_SUPPORT//chunpin_vmx_mgr
	if (STRLEN(ini_param->storeinfo_file_name) == 0)
		STRCPY(ini_param->storeinfo_file_name, "storeinfo.dvr");
#endif


	if (STRCMP(ini_param->info_file_name, ini_param->info_file_name_new) == 0 ||
		STRCMP(ini_param->ts_file_format, ini_param->ts_file_format_new) == 0 || 
		STRCMP(ini_param->ts_file_format, ini_param->ps_file_format) == 0)
	{
		return RET_FAILURE;
	}
	
//step1: init pvr manager
	if(g_pvr_mgr_info == NULL)
	{
		//init global params
		_pvr_mgr_malloc(g_pvr_mgr_info, sizeof(pvr_mgr_info), 1);
		
		STRCPY(g_pvr_mgr_info->config.dvr_path_prefix, ini_param->dvr_path_prefix);
		STRCPY(g_pvr_mgr_info->config.info_file_name, ini_param->info_file_name);
		STRCPY(g_pvr_mgr_info->config.info_file_name_new, ini_param->info_file_name_new);
		STRCPY(g_pvr_mgr_info->config.ts_file_format, ini_param->ts_file_format);
		STRCPY(g_pvr_mgr_info->config.ts_file_format_new, ini_param->ts_file_format_new);
		STRCPY(g_pvr_mgr_info->config.ps_file_format, ini_param->ps_file_format);
		STRCPY(g_pvr_mgr_info->config.test_file1, ini_param->test_file1);
		STRCPY(g_pvr_mgr_info->config.test_file2, ini_param->test_file2);

#if 1//def VMX_PVR_SUPPORT//chunpin_vmx_mgr
		STRCPY(g_pvr_mgr_info->config.storeinfo_file_name, ini_param->storeinfo_file_name);
#endif
		
		g_pvr_mgr_info->config.event_callback = ini_param->event_callback;
		g_pvr_mgr_info->config.prj_mode = ini_param->prj_mode;
		g_pvr_mgr_info->config.cfg_ext.pvr_mode = cfg->pvr_mode;			
		g_pvr_mgr_info->config.cfg_ext.pvr_name_in_unicode = cfg->pvr_name_in_unicode;
		g_pvr_mgr_info->config.cfg_ext.debug_enable = cfg->debug_enable;
		g_pvr_mgr_info->config.cfg_ext.update_tms_space_disable = cfg->update_tms_space_disable;
		
		INIT_LIST_HEAD(&g_pvr_mgr_info->pvr_list);
		INIT_LIST_HEAD(&g_pvr_mgr_info->partition_info.partition_list);
		for(i=0; i<PVR_MGR_REC_PARTITION_NUM; i++)
		{
			g_pvr_mgr_info->partition_info.rec_partition[i] = NULL;
		}
		g_pvr_mgr_info->partition_info.tms_partition = NULL;

		if(_pvr_mgr_task_init() != SUCCESS)
		{
			PDEBUG("PVR: _pvr_mgr_task_init fail\n", __FUNCTION__);
			return RET_FAILURE;
		}		
	}
	
//step2:init pvr engine
	if(ini_param->name_callback == NULL)
	{
		ini_param->name_callback = _pvr_mgr_calc_fullpath;
	}
	if(ini_param->local_time_callback == NULL)
	{
		ini_param->local_time_callback = _pvr_mgr_get_local_time;
	}
	if(ini_param->info_saving == NULL)
	{
		ini_param->info_saving = _pvr_mgr_update_userdata;
	}
	ini_param->rec_size_update_callback = _pvr_mgr_update_record_size;
	ini_param->event_callback = _pvr_mgr_event; //catch the eng CI+ msg!
	if(RET_SUCCESS == pvr_eng_attach(ini_param))
	{
		g_pvr_mgr_info->enable = 1;
	}
	
	return ret;
}

RET_CODE pvr_mgr_get_cfg(PPVR_MGR_CFG *ppcfg)
{
	if(g_pvr_mgr_info == NULL)
		return ERR_FAILUE;

	*ppcfg = &g_pvr_mgr_info->config.cfg_ext;

	return RET_SUCCESS;
}


BOOL pvr_mgr_detach(void)
{
	BOOL ret = TRUE;

	_pvr_mgr_cleanup_all();

	pvr_eng_detach();

	_pvr_mgr_task_delete();

	free(g_pvr_mgr_info);
	g_pvr_mgr_info = NULL;

	return ret;
}

PVR_HANDLE pvr_mgr_r_open(ppvr_mgr_record_param mgr_param, struct record_prog_param *eng_param)
{
	PVR_HANDLE ret = 0;
	ppvr_mgr_active_record record = NULL;
	ppvr_mgr_list_item record_item = NULL;
	BOOL dynamic_continuous_tms = FALSE; // indicate this record is continuous tms to lase tms record
	BOOL found_append_record = FALSE;
	
	if((eng_param->mode == RECORDING_TIMESHIFT) && eng_param->continuous_tms && (!eng_param->append_to_exist_file)) // get the paused tms hdl
	{
		record = _pvr_get_tms_record();
		if(record != NULL)
			dynamic_continuous_tms = TRUE;
		else
			record = _pvr_get_free_record();
	}
	else
		record = _pvr_get_free_record();

	//make full_path
	if(!mgr_param->full_path)
	{
		char string[256];
		ppvr_partition_info partition = NULL;
		partition = (eng_param->mode==RECORDING_NORMAL) ? 
			g_pvr_mgr_info->partition_info.rec_partition[0] : 
			g_pvr_mgr_info->partition_info.tms_partition;

		if ((partition->partition_info.type == 1) && (eng_param->record_file_size > MAX_FAT_FILE_SIZE))
		{
			eng_param->record_file_size = MAX_FAT_FILE_SIZE;
		}
			
		if(STRLEN(eng_param->folder_name) == 0)
		{
			struct PVR_DTM start_ptm;
			_pvr_mgr_get_local_time(&start_ptm);
			_pvr_mgr_add_record_name(string, (UINT16 *)eng_param->service_name);
			sprintf(eng_param->folder_name, DVR_RECORD_NAME_FORMAT, start_ptm.year, start_ptm.month, start_ptm.day, 
				start_ptm.hour, start_ptm.min, 	start_ptm.sec, 	string, RAND(1000));			
		}
		_pvr_mgr_calc_fullpath(partition->partition_info.mount_name, NULL, PVR_TYPE_PREX, 0, string);
		strcat(string, eng_param->folder_name);
		STRCPY(eng_param->folder_name, string);
	}

	if(dynamic_continuous_tms)
	{
		record_item = list_entry(record->listpointer, pvr_mgr_list_item, listpointer);
	}
	else
	{		
		if(eng_param->append_to_exist_file && eng_param->mode!=RECORDING_TIMESHIFT)
		{
			char mount_name[256];
			
			_pvr_mgr_get_mount_name(eng_param->folder_name, mount_name);
			record_item = _pvr_list_getitem_bypath(_pvr_list_get_by_mountname(mount_name), eng_param->folder_name);
			if(record_item == NULL)
			{
				// cann't file this record, diable append action
				found_append_record = FALSE;
				PDEBUG("cann't find record %s to append\n",eng_param->folder_name);
			}
			else
			{
				found_append_record = TRUE;
			}
		}
		

		if(record_item == NULL)
		{
			_pvr_mgr_malloc(record_item, sizeof(pvr_mgr_list_item), 1);
			_pvr_mgr_malloc(record_item->record_info, sizeof(pvr_mgr_rec_info), 1);
		}
			
		if(record_item->record_info->puser_data == NULL)
			_pvr_mgr_malloc(record_item->record_info->puser_data, sizeof(pvr_mgr_user_data), 1);

		record->type = PVR_MGR_REC_RECORD;
		record->listpointer = &record_item->listpointer;
		record_item->record_info->record.is_reencrypt = eng_param->is_reencrypt;
		record_item->record_info->record.rec_special_mode = eng_param->rec_special_mode;
		record_item->record_info->record.ca_mode = eng_param->ca_mode;

		_pvr_mgr_prepare_user_data(record_item, mgr_param, eng_param);
	}
	
	if(eng_param->record_file_size == 0)
		eng_param->record_file_size = 1*1024*1024;
	if(eng_param->mode == RECORDING_TIMESHIFT)
	{
		ppvr_partition_info partition = NULL;
		partition = g_pvr_mgr_info->partition_info.tms_partition;
		eng_param->tms_total_size = partition->partition_info.tms_size;
	}
	
	ret = pvr_eng_r_open(eng_param);
	if(ret != 0)
	{
		if(dynamic_continuous_tms && (record->r_handle != 0) && (record->r_handle != ret))
		{
			// eng has create new tms for some reason, need to delete old record!
			_pvr_mgr_free(record_item->record_info->puser_data);

			//check to delete tms?
			_pvr_list_del_by_idx(record->index);			
			_pvr_mgr_bookmark_dellist(record);			
			MEMSET(record, 0, sizeof(pvr_mgr_active_record));

			// reprepare record!
			if(record_item == NULL && !eng_param->append_to_exist_file)
			{
				_pvr_mgr_malloc(record_item, sizeof(pvr_mgr_list_item), 1);
				_pvr_mgr_malloc(record_item->record_info, sizeof(pvr_mgr_rec_info), 1);
			}
				
			if(record_item->record_info->puser_data == NULL)
				_pvr_mgr_malloc(record_item->record_info->puser_data, sizeof(pvr_mgr_user_data), 1);

			record->type = PVR_MGR_REC_RECORD;
			record->listpointer = &record_item->listpointer;

			_pvr_mgr_prepare_user_data(record_item, mgr_param, eng_param);
		}
			
		if((!dynamic_continuous_tms) || (dynamic_continuous_tms && (record->r_handle != 0) && (record->r_handle != ret)))
		{
			if(!found_append_record)
			{
				_pvr_mgr_add_record(record_item, eng_param->mode);
				_pvr_load_record_listinfo(record_item);
				record_item->record_info->is_update = 1;
				record_item->record_info->record_idx = record_item->record_info->record.index;
			}
			record->r_handle = ret;
			record->index = record_item->record_info->record_idx;
			INIT_LIST_HEAD(&record->bookmark_list);
		}
		// save user data to disk
		pvr_eng_set_user_data(record->r_handle, NULL, record_item->record_info->puser_data, sizeof(pvr_mgr_user_data));
	}
	else
	{
		_pvr_mgr_free(record_item->record_info->puser_data);
		if(!found_append_record)
		{
			_pvr_mgr_free(record_item->record_info);
			_pvr_mgr_free(record_item);
		}

		MEMSET(record, 0, sizeof(pvr_mgr_active_record));
	}
	
	return ret;
}


BOOL pvr_mgr_r_close(PVR_HANDLE *handle, struct record_stop_param *stop_param)
{
	ppvr_mgr_active_record record = NULL;
	ppvr_mgr_list_item item = NULL;
	UINT8 eng_ret = 0;
	REC_ENG_INFO item_info;
	ppvr_partition_info partition = NULL;
	
	pvr_return_val_if_fail(*handle != 0, FALSE);
	record = _pvr_get_record_byhandle(*handle);
	pvr_return_val_if_fail(record!=NULL, FALSE);

	item = list_entry(record->listpointer, pvr_mgr_list_item, listpointer);
	//make sure to save user data before record close!
	item->record_info->is_update = 1;

	MEMSET(&item_info, 0, sizeof(REC_ENG_INFO));

	// re-calcu size of tms record
	if ((record->index == TMS_INDEX) &&
		(g_pvr_mgr_info->config.cfg_ext.update_tms_space_disable == 0))
	{
		partition = g_pvr_mgr_info->partition_info.tms_partition;
		_pvr_mgr_fpartition_info(&partition->partition_info);
	}
	
	eng_ret = pvr_eng_r_close(handle, stop_param);

	// re-calcu size according to deleted normal record
	if ((record->index > TMS_INDEX) &&
		(g_pvr_mgr_info->config.cfg_ext.update_tms_space_disable == 0))
	{
		partition = g_pvr_mgr_info->partition_info.rec_partition[0];
		_pvr_mgr_fpartition_info(&partition->partition_info);
	}
	
	if(eng_ret == 2) // not close, like continue-tms
	{
		pvr_eng_get_record_info(0, item->record_dir_path, &item_info);
		_pvr_list_trans_eng_info(&item->record_info->record, &item_info);
	}
	else
	{
		if(eng_ret == 1) // normal close! (save to disk)
		{
			pvr_eng_get_record_info(0, item->record_dir_path, &item_info);
			_pvr_list_trans_eng_info(&item->record_info->record, &item_info);
		}
		else // 0: close and delete file!
		{
			item->record_info->record.is_recording = 0;
		}
		
		record->r_handle = 0;
		if(record->p_handle != 0)
		{
			record->type = PVR_MGR_REC_PLAYBACK;
		}
		else
		{		
			_pvr_mgr_free(item->record_info->puser_data);

			//check to delete tms?
			if((!eng_ret) || (record->index == TMS_INDEX))
			{
				_pvr_list_del_by_idx(record->index);
			}
			
			_pvr_mgr_bookmark_dellist(record);
			
			MEMSET(record, 0, sizeof(pvr_mgr_active_record));
		}
	}
	
	*handle = 0;

	return TRUE;
	
}

RET_CODE pvr_mgr_ioctl(PVR_HANDLE handle, UINT32 cmd_type, UINT32 param1, UINT32 param2)
{
	RET_CODE ret = RET_SUCCESS;
	ppvr_mgr_list list = _pvr_list_get_cur_list();
	ppvr_mgr_list_item record_item = NULL;
	ppvr_mgr_active_record record = NULL;
	UINT8 mode = (param2&0x00FF0000)>>16;
	UINT16 param = param2&0xFFFF;	
	ppvr_partition_info part_info = ((param == TMS_INDEX) && (mode == 0))
		? (g_pvr_mgr_info->partition_info.tms_partition) 
		: (g_pvr_mgr_info->partition_info.rec_partition[0]);

	switch(cmd_type)
	{
		case PVR_MGRIO_RECORD_GETCNT:
			*(UINT32 *)param1 = _pvr_list_get_record_num();
			break;
			
		case PVR_MGRIO_RECORD_GETINFO:
			if (part_info == NULL)
			{
				ret = RET_FAILURE;
				break;
			}
			list = _pvr_list_get_by_mountname(part_info->partition_info.mount_name);
			_pvr_list_get_record_info(list, param, mode, (struct ListInfo *)param1);
			break;
			
		case PVR_MGRIO_RECORD_SETINFO:
			{
				if (part_info == NULL)
				{
					ret = RET_FAILURE;
					break;
				}
				list = _pvr_list_get_by_mountname(part_info->partition_info.mount_name);
				record_item = _pvr_list_getitem(list, mode, param);
				if(record_item != NULL)
				{
					MEMCPY(&record_item->record_info->record, (struct ListInfo *)param1, sizeof(struct ListInfo));
					record_item->record_info->is_update = 1;
					REC_ENG_INFO info;
					MEMSET(&info, 0 ,sizeof(REC_ENG_INFO));
					pvr_eng_get_record_info(0, record_item->record_dir_path, &info);
					_pvr_list_trans_info_to_eng(&info, &record_item->record_info->record);
					pvr_eng_set_record_info(0, record_item->record_dir_path, &info);
				}
			}
			break;
			
		case PVR_MGRIO_RECORD_GETIDX:
			{pvr_return_val_if_fail(handle != 0, RET_FAILURE);

			record = _pvr_get_record_byhandle(handle);
			pvr_return_val_if_fail(record != NULL, RET_FAILURE);

			record_item = list_entry(record->listpointer, pvr_mgr_list_item, listpointer);
			pvr_return_val_if_fail(record_item != NULL, RET_FAILURE);

			*(UINT32 *)param1 = record_item->record_info->record_idx;		
			}break;
		case PVR_MGRIO_RECORD_GET_PATH:
			{
				part_info = (param == TMS_INDEX) 
					? (g_pvr_mgr_info->partition_info.tms_partition) 
					: (g_pvr_mgr_info->partition_info.rec_partition[0]);
				if (part_info == NULL)
				{
					ret = RET_FAILURE;
					break;
				}
				list = _pvr_list_get_by_mountname(part_info->partition_info.mount_name);
				record_item = _pvr_list_getitem_byidx(list, param);
				pvr_return_val_if_fail(record_item != NULL, 0);
		
				STRCPY((char *)param1, record_item->record_dir_path);
			}
			break;
			
		case PVR_MGRIO_RECORD_CHK_DEL:
			part_info = g_pvr_mgr_info->partition_info.rec_partition[0];
			if (part_info == NULL)
			{
				ret = RET_FAILURE;
				break;
			}
			list = _pvr_list_get_by_mountname(part_info->partition_info.mount_name);
			*(UINT32 *)param1 = _pvr_list_check_del(list);
			break;
			
		case PVR_MGRIO_RECORD_CLR_DEL:
			part_info = g_pvr_mgr_info->partition_info.rec_partition[0];
			if (part_info == NULL)
			{
				ret = RET_FAILURE;
				break;
			}
			list = _pvr_list_get_by_mountname(part_info->partition_info.mount_name);
			_pvr_list_clear_del(list);
			break;
			
		case PVR_MGRIO_RECORD_SAVE:
			if (part_info == NULL)
			{
				ret = RET_FAILURE;
				break;
			}
			list = _pvr_list_get_by_mountname(part_info->partition_info.mount_name);
			record_item = _pvr_list_getitem(list, mode, param);
			pvr_return_val_if_fail(record_item != NULL, RET_FAILURE);
			_pvr_list_save_record(list, record_item);
			break;
			
		case PVR_MGRIO_RECORD_SAVE_ALL:
			part_info = g_pvr_mgr_info->partition_info.rec_partition[0];
			if (part_info == NULL)
			{
				ret = RET_FAILURE;
				break;
			}
			list = _pvr_list_get_by_mountname(part_info->partition_info.mount_name);
			_pvr_list_save_list(list);
			break;
		case PVR_MGRIO_PARTITION_GETINFO:
			{
				struct dvr_HDD_info *partition_info = (struct dvr_HDD_info *)param1;
				char *mount_name = (char *)param2;

				ret = _pvr_mgr_get_partition_info(mount_name, partition_info);
			}
			break;
		
		case PVR_MGRIO_PARTITION_TEST:
			{char *mount_name = (char *)param2;
			ppvr_partition_info partition = NULL;

			partition = _pvr_mgr_get_partition(mount_name);
			if(partition == NULL)
			{
				PERROR("%s can not find partition %s!\n", __FUNCTION__, mount_name);
				return RET_FAILURE;
			}

			_pvr_mgr_fpartition_test(&(partition->partition_info));
			}break;

		case PVR_MGRIO_PARTITION_GETREC:
			_pvr_mgr_get_cur_mode((char *)param1, NULL);
			break;
			
		case PVR_MGRIO_PARTITION_GETTMS:
			_pvr_mgr_get_cur_mode(NULL, (char *)param1);
			break;
			
		case PVR_MGRIO_PARTITION_GETMODE:
			*(UINT32 *)param1 = _pvr_mgr_get_cur_mode(NULL, NULL);
			break;

		case PVR_MGRIO_PARTITION_INITSIZE:
			{ppvr_partition_info partition = NULL;
			partition = _pvr_mgr_get_partition((char *)param1);
			if(partition == NULL)
			{
				PERROR("pvr has no partition!\n");
				ret = RET_FAILURE;
			}
			else
			{
				g_pvr_mgr_info->partition_info.app_alloc_tms_size = FALSE;
				_pvr_mgr_fpartition_info(&partition->partition_info);
			}			
			}break;
		
		case PVR_MGRIO_SAVE_CUR_POS:
			_pvr_mgr_save_cur_pos(handle);
			break;
			
		case PVR_MGRIO_GET_LAST_POS:
			if (part_info == NULL)
			{
				ret = RET_FAILURE;
				break;
			}
			list = _pvr_list_get_by_mountname(part_info->partition_info.mount_name);
			record_item = _pvr_list_getitem(list, mode, param);
			pvr_return_val_if_fail(record_item != NULL, RET_FAILURE);
			*(UINT32 *)param1 = _pvr_mgr_get_last_pos(record_item);
			break;
		
		case PVR_MGRIO_GET_LAST_POSPTM:
			if (part_info == NULL)
			{
				ret = RET_FAILURE;
				break;
			}
			list = _pvr_list_get_by_mountname(part_info->partition_info.mount_name);
			record_item = _pvr_list_getitem(list, mode, param);
			pvr_return_val_if_fail(record_item != NULL, RET_FAILURE);
			*(UINT32 *)param1 = _pvr_mgr_get_last_posptm(record_item);	
			break;
			
		case PVR_MGRIO_BOOKMARK_SET:
			if (part_info == NULL)
			{
				ret = RET_FAILURE;
				break;
			}
			list = _pvr_list_get_by_mountname(part_info->partition_info.mount_name);
			record_item = _pvr_list_getitem(list, mode, param);
			ret = _pvr_mgr_bookmark_set(record_item, param1);
			break;
			
		case PVR_MGRIO_BOOKMARK_GET:
			if (part_info == NULL)
			{
				ret = RET_FAILURE;
				break;
			}
			mode = ((*(UINT32 *)param2)&0x00FF0000)>>16;
			param = (*(UINT32 *)param2)&0xFFFF;	
			list = _pvr_list_get_by_mountname(part_info->partition_info.mount_name);
			record_item = _pvr_list_getitem(list, mode, param);
			if(record_item)
			{
				_pvr_mgr_bookmark_get(record_item, param1);
				*(UINT32 *)param2 = record_item->record_info->puser_data->bookmark_num;
			}
			else
			{
				*(UINT32 *)param2 = 0;
			}
			break;
						
		case PVR_MGRIO_REPEATMARK_SET:
			if (part_info == NULL)
			{
				ret = RET_FAILURE;
				break;
			}
			list = _pvr_list_get_by_mountname(part_info->partition_info.mount_name);
			record_item = _pvr_list_getitem(list, mode, param);
			ret = _pvr_mgr_repeatmark_set(record_item, param1);
			break;
			
		case PVR_MGRIO_REPEATMARK_GET:
			if (part_info == NULL)
			{
				ret = RET_FAILURE;
				break;
			}
			mode = ((*(UINT32 *)param2)&0x00FF0000)>>16;
			param = (*(UINT32 *)param2)&0xFFFF;	
			list = _pvr_list_get_by_mountname(part_info->partition_info.mount_name);
			record_item = _pvr_list_getitem(list, mode, param);
			if(record_item)
			{
				_pvr_mgr_repeatmark_get(record_item, param1);
				*(UINT32 *)param2 = record_item->record_info->puser_data->repeat_AB;
			}
			else
			{
				*(UINT32 *)param2 = 0;
			}
			break;
			
		case PVR_MGRIO_REPEATMARK_CLR:
			if (part_info == NULL)
			{
				ret = RET_FAILURE;
				break;
			}
			list = _pvr_list_get_by_mountname(part_info->partition_info.mount_name);
			record_item = _pvr_list_getitem(list, mode, param);
			ret = _pvr_mgr_repeatmark_set(record_item, -1);
			break;
			
		case PVR_MGRIO_AGELIMIT_SET:
			if (part_info == NULL)
			{
				ret = RET_FAILURE;
				break;
			}
			{record_agelimit_item *item = (record_agelimit_item *)param1;
			list = _pvr_list_get_by_mountname(part_info->partition_info.mount_name);
			record_item = _pvr_list_getitem(list, mode, param);
			_pvr_mgr_agelimit_set(record_item, item->ptm, item->age);
			}break;
			
		case PVR_MGRIO_AGELIMIT_GET:
			if (part_info == NULL)
			{
				ret = RET_FAILURE;
				break;
			}
			{record_agelimit_item *item = (record_agelimit_item *)param1;
			list = _pvr_list_get_by_mountname(part_info->partition_info.mount_name);
			record_item = _pvr_list_getitem(list, mode, param);
			item->age = _pvr_mgr_agelimit_get(record_item, item->ptm);
			}break;
			
		case PVR_MGRIO_RATINGCTL_SET:
			if (part_info == NULL)
			{
				ret = RET_FAILURE;
				break;
			}
			{record_ratingctl_item *item = (record_ratingctl_item *)param1;
			list = _pvr_list_get_by_mountname(part_info->partition_info.mount_name);
			record_item = _pvr_list_getitem(list, mode, param);
			_pvr_mgr_ratingctl_set(record_item, item->ptm, item->rating);
			}break;
			
		case PVR_MGRIO_RATINGCTL_GET:
			if (part_info == NULL)
			{
				ret = RET_FAILURE;
				break;
			}
			{record_ratingctl_item *item = (record_ratingctl_item *)param1;
			list = _pvr_list_get_by_mountname(part_info->partition_info.mount_name);
			record_item = _pvr_list_getitem(list, mode, param);
			item->rating = _pvr_mgr_ratingctl_get(record_item, item->ptm);
			}break;

		case PVR_MGRIO_CHECK_TMS2REC:
			*(UINT32 *)param1 = TRUE;
			if((g_pvr_mgr_info->partition_info.rec_partition[0] == NULL) 
				|| (g_pvr_mgr_info->partition_info.tms_partition == NULL) 
				|| (g_pvr_mgr_info->partition_info.rec_partition[0] != g_pvr_mgr_info->partition_info.tms_partition))
			{
				*(UINT32 *)param1 = FALSE;
			}
			break;

		case PVR_MGRIO_CHECK_RECORD:
			if (part_info == NULL)
			{
				ret = RET_FAILURE;
				break;
			}
			list = _pvr_list_get_by_mountname(part_info->partition_info.mount_name);
			record_item = _pvr_list_getitem(list, mode, param);
			pvr_return_val_if_fail(record_item != NULL, RET_FAILURE);
			record = _pvr_get_record_bypath(record_item->record_dir_path);
			pvr_return_val_if_fail(record != NULL, RET_FAILURE);
			ret = (record->r_handle != 0) ? RET_SUCCESS : RET_FAILURE;
			break;

		case PVR_MGRIO_CHECK_PLAYBACK:
			if (part_info == NULL)
			{
				ret = RET_FAILURE;
				break;
			}
			list = _pvr_list_get_by_mountname(part_info->partition_info.mount_name);
			record_item = _pvr_list_getitem(list, mode, param);
			pvr_return_val_if_fail(record_item != NULL, RET_FAILURE);
			record = _pvr_get_record_bypath(record_item->record_dir_path);
			pvr_return_val_if_fail(record != NULL, RET_FAILURE);
			ret = (record->p_handle != 0) ? RET_SUCCESS : RET_FAILURE;
			break;
			
		case PVR_ERIO_TMS2REC:
			part_info = g_pvr_mgr_info->partition_info.rec_partition[0];
			if (part_info == NULL)
			{
				ret = RET_FAILURE;
				break;
			}
			{struct dvr_HDD_info hdd_info;
			UINT16 index;
			list = _pvr_list_get_by_mountname(part_info->partition_info.mount_name);
			index = _pvr_list_alloc_index(list);
			REC_ENG_INFO item_info;
			BOOL can_trans = FALSE;

			pvr_mgr_ioctl(0, PVR_MGRIO_CHECK_TMS2REC, (UINT32)&can_trans, 0);
			if(!can_trans)
				break;
			
			record = _pvr_get_record_byhandle(handle);
			record_item = _pvr_list_getitem_byidx(list, record->index);

			*(UINT32 *)param1 = 0;

			if(RET_SUCCESS != _pvr_mgr_get_partition_info(NULL, &hdd_info))
				break;
			
			pvr_eng_get_record_info(handle, NULL, &item_info);
			if(hdd_info.rec_size < item_info.size)
				break;
			
			ret = pvr_eng_ioctl(handle, cmd_type, param1, param2);

			if((ret != RET_SUCCESS) || (*(UINT32 *)param1 == 0))
				break;

			record_item->record_info->puser_data->record_idx = index;
			record_item->record_info->record.index = index;
			record_item->record_info->record_idx = index;	
			record->index = index;

			list_del(&record_item->listpointer);
			_pvr_list_insert_item(list, record_item);	
			record_item->record_info->is_update = 1;
			pvr_eng_set_user_data(handle, record_item->record_dir_path, record_item->record_info->puser_data, sizeof(pvr_mgr_user_data));
			}break;
		
		case PVR_MGRIO_PARTITION_SETUSEAGE:
			{char *mount_name = (char *)param1;
			UINT8 use = param2;

			_pvr_mgr_set_partition_use(use, mount_name);		
			}break;
		
		case PVR_MGRIO_CACW_GET:
			if (part_info == NULL)
			{
				ret = RET_FAILURE;
				break;
			}
			list = _pvr_list_get_by_mountname(part_info->partition_info.mount_name);
			record_item = _pvr_list_getitem(list, mode, param);
			ret = _pvr_mgr_get_ca_cw(record_item, param1);
			break;

		case PVR_MGRIO_CACW_SET:
			if (part_info == NULL)
			{
				ret = RET_FAILURE;
				break;
			}
			list = _pvr_list_get_by_mountname(part_info->partition_info.mount_name);
			record_item = _pvr_list_getitem(list, mode, param);
			ret = _pvr_mgr_set_ca_cw(record_item, param1);
			break;

		case PVR_MGRIO_CACW_DUMP:
			if (part_info == NULL)
			{
				ret = RET_FAILURE;
				break;
			}
			list = _pvr_list_get_by_mountname(part_info->partition_info.mount_name);
			record_item = _pvr_list_getitem(list, mode, param);
			ret = _pvr_mgr_dump_ca_cw(record_item);
			break;

		case PVR_MGRIO_EVENT_NAME_SET:
			if (part_info == NULL)
			{
				ret = RET_FAILURE;
				break;
			}
			{record_event_item *item = (record_event_item *)param1;
			list = _pvr_list_get_by_mountname(part_info->partition_info.mount_name);
			record_item = _pvr_list_getitem(list, mode, param);
			ret = _pvr_data_set_event_name(record_item, item->pEvent_name);
			}break;

		case PVR_MGRIO_EVENT_NAME_GET:
			if (part_info == NULL)
			{
				ret = RET_FAILURE;
				break;
			}
			{record_event_item *item = (record_event_item *)param1;
			list = _pvr_list_get_by_mountname(part_info->partition_info.mount_name);
			record_item = _pvr_list_getitem(list, mode, param);
			item->pEvent_name = (UINT8 *)_pvr_data_get_event_name(record_item);
			}break;

		case PVR_MGRIO_EVENT_DETAIL_SET:
			if (part_info == NULL)
			{
				ret = RET_FAILURE;
				break;
			}
			{record_event_detail_item *item = (record_event_detail_item *)param1;
			list = _pvr_list_get_by_mountname(part_info->partition_info.mount_name);
			record_item = _pvr_list_getitem(list, mode, param);
			ret = _pvr_data_set_event_detail(record_item, item->pDetail, item->len, item->type);
			}break;

		case PVR_MGRIO_EVENT_DETAIL_GET:
			if (part_info == NULL)
			{
				ret = RET_FAILURE;
				break;
			}
			{record_event_detail_item *item = (record_event_detail_item *)param1;
			list = _pvr_list_get_by_mountname(part_info->partition_info.mount_name);
			record_item = _pvr_list_getitem(list, mode, param);
			item->pDetail = (UINT8 *)_pvr_data_get_event_detail(record_item, item->type);
			}break;

		case PVR_MGRIO_GETIDX_BY_PATH:
			part_info = g_pvr_mgr_info->partition_info.rec_partition[0];
			if (part_info == NULL)
			{
				ret = RET_FAILURE;
				break;
			}
			{list = _pvr_list_get_by_mountname(part_info->partition_info.mount_name);

			record_item = _pvr_list_getitem_bypath(list, (const char *)param2);
		
			if(record_item != NULL)
				*(UINT32 *)param1 = record_item->record_info->record_idx;
			}break;

		case PVR_MGRIO_SECRTKEY_SET:
			part_info = (param == TMS_INDEX) 
				? (g_pvr_mgr_info->partition_info.tms_partition) 
				: (g_pvr_mgr_info->partition_info.rec_partition[0]);
			if (part_info == NULL)
			{
				ret = RET_FAILURE;
				break;
			}
			{UINT16 index = (param2&0xFFFF0000)>>16;
			list = _pvr_list_get_by_mountname(part_info->partition_info.mount_name);

			record_item = _pvr_list_getitem_byidx(list, param);
			pvr_return_val_if_fail(record_item != NULL, RET_FAILURE);

			pvr_eng_set_header_key(record_item->record_dir_path, (UINT8 *)param1,(UINT32)index);
			}break;

		case PVR_MGRIO_SECRTKEY_GET:
			part_info = (param == TMS_INDEX) 
				? (g_pvr_mgr_info->partition_info.tms_partition) 
				: (g_pvr_mgr_info->partition_info.rec_partition[0]);
			if (part_info == NULL)
			{
				ret = RET_FAILURE;
				break;
			}
			{UINT16 index = (param2&0xFFFF0000)>>16;
			list = _pvr_list_get_by_mountname(part_info->partition_info.mount_name);

			record_item = _pvr_list_getitem_byidx(list, param);
			pvr_return_val_if_fail(record_item != NULL, RET_FAILURE);

			pvr_eng_get_header_key(record_item->record_dir_path, (UINT8 *)param1, (UINT32)index);
			}break;
			
		case PVR_MGRIO_AUDIO_TYPE_SET:
			if (part_info == NULL)
			{
				ret = RET_FAILURE;
				break;
			}
			list = _pvr_list_get_by_mountname(part_info->partition_info.mount_name);
			record_item = _pvr_list_getitem(list, mode, param);
			_pvr_mgr_audio_type_set(record_item, (UINT8 *)param1, (UINT8)((param2>>24)&0xFF));
			break;
		
		case PVR_MGRIO_AUDIO_TYPE_GET:
			if (part_info == NULL)
			{
				ret = RET_FAILURE;
				break;
			}
			list = _pvr_list_get_by_mountname(part_info->partition_info.mount_name);
			record_item = _pvr_list_getitem(list, mode, param);
			_pvr_mgr_audio_type_get(record_item, (UINT8 *)param1, (UINT8)((param2>>24)&0xFF));
			break;

		case PVR_MGRIO_CHK_TMS_CAPABILITY: // check timeshift capability
			ret = _pvr_mgr_chk_tms_capability(param1, (PTMS_INFO)param2);
			break;

		case PVR_MGRIO_CIPLUS_URI_SET:
			if (part_info == NULL)
			{
				ret = RET_FAILURE;
				break;
			}
			list = _pvr_list_get_by_mountname(part_info->partition_info.mount_name);
			record_item = _pvr_list_getitem(list, mode, param);
			_pvr_mgr_set_ciplus_uri(record_item, (record_ciplus_uri_item *)param1);
			break;

		case PVR_MGRIO_CIPLUS_STOID_GET:
			{int need_free = FALSE;
			UINT32 len = 0;
			if (part_info == NULL)
			{
				ret = RET_FAILURE;
				break;
			}
			list = _pvr_list_get_by_mountname(part_info->partition_info.mount_name);
			record_item = _pvr_list_getitem(list, mode, param);
			pvr_return_val_if_fail(record_item != NULL, RET_FAILURE);
			
			if(record_item->record_info->puser_data == NULL)
			{
				_pvr_mgr_malloc(record_item->record_info->puser_data, sizeof(pvr_mgr_user_data), 1);
				need_free = TRUE;
			}
			if(FALSE != pvr_eng_get_user_data(0, record_item->record_dir_path, record_item->record_info->puser_data, &len))
			{
				((UINT32 *)param1)[0] = record_item->record_info->puser_data->sto_id[0];		
				((UINT32 *)param1)[1] = record_item->record_info->puser_data->sto_id[1];		
			}
			else
			{
				PDEBUG("IO PVR_MGRIO_CIPLUS_STOID_GET fail at pvr_eng_get_user_data!\n");
			}
			
			if(need_free)
				_pvr_mgr_free(record_item->record_info->puser_data);
				
			break;}

		case PVR_MGRIO_IDENTIFY_RECORD:
			{//add to some record list
			PREC_ENG_INFO item_info = NULL;
			char *path = (char *)param1;
			char mount_name[256];

			_pvr_mgr_malloc(item_info, sizeof(REC_ENG_INFO), 1);
					 
			if(TRUE == pvr_eng_is_our_file(path, item_info))
			{		
				_pvr_mgr_get_mount_name(path, mount_name);
				*(int *)param2 = _pvr_list_add_item(_pvr_list_get_by_mountname(mount_name), path, item_info);
			}
			_pvr_mgr_free(item_info);
			}
			break;
	#if 1//def VMX_PVR_SUPPORT
			
		case PVR_MGRIO_SAVE_INFO_HEADER:
			ret=_pvr_mgr_data_write_store_info_header(handle,(struct store_info_header *)param1);
			break;
			
		case PVR_MGRIO_GET_INFO_HEADER:
			{
				ppvr_mgr_active_record record = NULL;
				if(handle == 0)
				{
					if (part_info == NULL)
					{
						ret = FALSE;
						break;
					}
					list = _pvr_list_get_by_mountname(part_info->partition_info.mount_name);
					record_item = _pvr_list_getitem(list, mode, param);
					if (record_item != NULL)
					{
						ret=_pvr_mgr_data_read_store_info_header(record_item, (struct store_info_header *)param1);
					}
					else
					{
						ret=FALSE;
					}
				}
				else
				{
					record = _pvr_get_record_byhandle(handle);
					pvr_return_val_if_fail(record!=NULL, FALSE);	
					record_item = list_entry(record->listpointer, pvr_mgr_list_item, listpointer);
					pvr_return_val_if_fail(record_item!=NULL, FALSE);
					ret=_pvr_mgr_data_read_store_info_header(record_item, (struct store_info_header *)param1);				
				}
			}
			break;
			
		case PVR_MGRIO_SAVE_STORE_INFO:
			ret=_pvr_mgr_data_write_storeinfo(handle, (struct store_info_data_single*)param1, param2);
			break;
			
		case PVR_MGRIO_GET_STORE_INFO:
			{
				struct store_info_param *storeinfo_param=param1;
				ppvr_mgr_active_record record = NULL;

				if(handle == 0)
				{
					if (part_info == NULL)
					{
						ret = FALSE;
						break;
					}
					list = _pvr_list_get_by_mountname(part_info->partition_info.mount_name);
					record_item = _pvr_list_getitem(list, mode, param);
					if (record_item != NULL)
					{
						ret=_pvr_mgr_data_read_storeinfo(record_item,storeinfo_param->storeinfodata, storeinfo_param->ptm);
					}
					else
					{
						ret=FALSE;
					}
				}
				else
				{
					record = _pvr_get_record_byhandle(handle);
					pvr_return_val_if_fail(record!=NULL, FALSE);	
					record_item = list_entry(record->listpointer, pvr_mgr_list_item, listpointer);
					pvr_return_val_if_fail(record_item!=NULL, FALSE);
					ret=_pvr_mgr_data_read_storeinfo(record_item,storeinfo_param->storeinfodata, storeinfo_param->ptm);
				}
			}
			break;
			
	#endif		
		case PVR_EPIO_GET_CAS9_MAT_RATING:
			if (handle == 0)
			{
				if (part_info == NULL)
				{
					ret = RET_FAILURE;
					break;
				}
				list = _pvr_list_get_by_mountname(part_info->partition_info.mount_name);
				record_item = _pvr_list_getitem(list, mode, param);
				if (record_item != NULL)
					ret = pvr_eng_ioctl(handle, cmd_type, param1, (UINT32)record_item->record_dir_path);
				else
					ret = RET_FAILURE;
			}
			else
			{
				ret = pvr_eng_ioctl(handle, cmd_type, param1, 0);
			}
			break;

		default:
			ret = pvr_eng_ioctl(handle, cmd_type, param1, param2);
			break;
	}
	
	return ret;
}

PVR_HANDLE pvr_mgr_p_open(ppvr_mgr_playback_param mgr_param, struct playback_param *eng_param)
{
	PVR_HANDLE ret = 0;
	ppvr_mgr_active_record record = NULL;
	ppvr_mgr_list_item record_item = NULL;
	UINT32 len;
	UINT16 i;
	char mount_name[256];
	ppvr_mgr_list list = NULL;
	
	//ZZL TODO:
	//make full_path
	if(eng_param->index == 0)
	{
		//add to some record list
		PREC_ENG_INFO item_info = NULL;

		_pvr_mgr_malloc(item_info, sizeof(REC_ENG_INFO), 1);
				 
		if(TRUE == pvr_eng_is_our_file(eng_param->path, item_info))
		{		
			_pvr_mgr_get_mount_name(eng_param->path, mount_name);
			eng_param->index = _pvr_list_add_item(_pvr_list_get_by_mountname(mount_name), eng_param->path, item_info);
		}
		else
		{
			PDEBUG("Error, cannot recognize this record!!!\n");
			return 0;
		}
	}

	if(eng_param->index > 0)
	{		
		list = _pvr_list_get_by_mountname((eng_param->index == TMS_INDEX) 
			? (g_pvr_mgr_info->partition_info.tms_partition->partition_info.mount_name) 
			: (g_pvr_mgr_info->partition_info.rec_partition[0]->partition_info.mount_name));
		record_item = _pvr_list_getitem_byidx(list, eng_param->index);
		pvr_return_val_if_fail(record_item != NULL, 0);
		
		STRCPY(eng_param->path, record_item->record_dir_path);
	}
	else
	{
		PDEBUG("Error, index 0, cannot playback!!!\n");
		return 0;
	}
	
	if(eng_param->start_mode & P_OPEN_FROM_LAST_POS)
	{
		eng_param->start_mode &= (~P_OPEN_FROM_LAST_POS);
		eng_param->start_mode &= P_OPEN_FROM_POS;
		pvr_mgr_ioctl(0, PVR_MGRIO_GET_LAST_POS, (UINT32)&eng_param->start_pos, (0<<16)|eng_param->index);
	}

	record = _pvr_get_record_bypath(eng_param->path);
	if(record == NULL)
	{
		record = _pvr_get_free_record();
		pvr_return_val_if_fail(record!=NULL, 0);
	}
	
	if(record->r_handle != 0)
	{
		record->type = PVR_MGR_REC_RECANDPLY;
	}
	else
	{
		record->listpointer = &record_item->listpointer;
		record->type = PVR_MGR_REC_PLAYBACK;
		if(record_item->record_info->puser_data == NULL)
			_pvr_mgr_malloc(record_item->record_info->puser_data, sizeof(pvr_mgr_user_data), 1);
	}

	g_pvr_mgr_info->player_reencrypt_state = 0;
	record->p_param1 = record->p_param2 = -1;
	ret = pvr_eng_p_open(eng_param);
	if(ret != 0)
	{
		record->p_handle = ret;
		if(record->r_handle != 0)
		{
			record->type = PVR_MGR_REC_RECANDPLY;
		}
		else
		{
			record->listpointer = &record_item->listpointer;
			record->type = PVR_MGR_REC_PLAYBACK;
			if(record_item->record_info->puser_data == NULL)
				_pvr_mgr_malloc(record_item->record_info->puser_data, sizeof(pvr_mgr_user_data), 1);
			pvr_eng_get_user_data(record->p_handle, NULL, record_item->record_info->puser_data, &len);

			_pvr_list_trans_mgr_info(record_item->record_info->is_update, &record_item->record_info->record, record_item->record_info->puser_data);
			_pvr_mgr_bookmark_load(record_item);
		}
	}
	else
	{
		if(record->r_handle == 0)
			MEMSET(record, 0, sizeof(pvr_mgr_active_record));
	}
		
	return ret;
}

BOOL pvr_mgr_p_close(PVR_HANDLE *handle, struct playback_stop_param *stop_param)
{
	ppvr_mgr_active_record record = NULL;
	ppvr_mgr_list_item item = NULL;
	PVR_HANDLE temp_handle = *handle;
	
	pvr_return_val_if_fail(*handle != 0, FALSE);

	g_pvr_mgr_info->player_reencrypt_state = 2;
	pvr_eng_p_close(handle, stop_param);

	record = _pvr_get_record_byhandle(temp_handle);
	pvr_return_val_if_fail(record!=NULL, FALSE);

	item = list_entry(record->listpointer, pvr_mgr_list_item, listpointer);

	record->p_handle = 0;
	if(record->r_handle != 0)
	{
		record->type = PVR_MGR_REC_RECORD;
	}
	else
	{
		_pvr_mgr_free(item->record_info->puser_data);

		//check to delete tms?
		if(record->index == TMS_INDEX)
		{
			_pvr_list_del_by_idx(record->index);
		}
		
		_pvr_mgr_bookmark_dellist(record);
		
		MEMSET(record, 0, sizeof(pvr_mgr_active_record));
	}
	
	return TRUE;
}

RET_CODE pvr_mgr_p_play_mode(PVR_HANDLE handle, UINT8 new_state, UINT32 param)
{
	return pvr_eng_p_play_mode(handle, new_state, param);
}

//##: register one partition.
INT32 pvr_register_partition(struct pvr_register_info *info)
{
	struct pvr_register_info *reg_info = info;

	if(info->sync == 0)
	{
		reg_info = (struct pvr_register_info *)MALLOC(sizeof(struct pvr_register_info));
		MEMCPY(reg_info, info, sizeof(struct pvr_register_info));
	}

	_pvr_mgr_send_message(0, PVR_MGR_REGISTER, 0, (UINT32)reg_info, 0, info->sync);


	return (g_pvr_mgr_info->register_state >= 0) ? SUCCESS : ERR_FAILUE;
}

INT32 pvr_cleanup_all(void)
{
	_pvr_mgr_send_message(NULL, PVR_MGR_CLEANUP, 0, 0, 0, TRUE);
	return 0;
}

INT32 pvr_cleanup_device(char type)
{
	_pvr_mgr_send_message(NULL, PVR_MGR_CLEANUP_DEVICE, type, 0, 0, TRUE);
	return 0;
}

INT32 pvr_cleanup_partition(struct pvr_clean_info *param)
{
	_pvr_mgr_send_message(NULL, PVR_MGR_CLEANUP_PARTITION, 0, param, 0, TRUE);
	return 0;
}

RET_CODE pvr_mgr_copy(struct ListInfo rl_info, struct copy_param cp_param)
{
	char path[1024];
	struct playback_param playback_info;
	
	MEMSET(&playback_info, 0, sizeof(struct playback_param));
	
	playback_info.state = NV_STEP;
	playback_info.start_time = 0;
	playback_info.start_mode = P_OPEN_FROM_HEAD;
	playback_info.start_pos = 0;
	playback_info.dmx_id = 2;
	playback_info.live_dmx_id = 0;
	playback_info.preview_mode = 1;
	playback_info.speed = 1;
	playback_info.index = rl_info.index;
	if(rl_info.index > 0)
	{
		pvr_mgr_ioctl(0, PVR_MGRIO_RECORD_GET_PATH, (UINT32)path, rl_info.index);
		//pvr_get_path(rl_info.index, path);
	}
	else
		return RET_FAILURE;
	
	pvr_eng_copy(&playback_info, cp_param);
	
	_pvr_mgr_add_copy_record( rl_info,  path);

	return RET_SUCCESS;
}

UINT16 pvr_mgr_set_extfile(char *path, BOOL full_path)
{
    if(path == NULL)
    {
        PDEBUG("pvr_mgr_set_extfile::PUSH VOD dir is NULL\n");
        return 0;
    }
    
    if(full_path)
    {
        return pvr_eng_parse_ts_file(path);
    }
    else
    {
        DIR *dir = NULL;
        F_Dirent item;
        char dirPath[256];
        pvr_eng_parse_ts_file_dir(path);
        dir = (DIR *)_opendir(path);
        if(dir)
        {
            while(_readdir(dir, &item) == TRUE)
            {
                if (item.is_dir)
                {
                    MEMSET(dirPath,0,sizeof(dirPath));
                    strcpy(dirPath,path);
                    strcat(dirPath,"/");
                    strcat(dirPath,item.name);
                    pvr_eng_parse_ts_file_dir(dirPath);
                }
            }
            _closedir(dir);
        }
    }
}

RET_CODE _pvr_mgr_add_file(char *dir_path)
{
	ppvr_mgr_list list = NULL;
	PREC_ENG_INFO item_info = NULL;

    list = (ppvr_mgr_list)_pvr_list_get_mgrlist(dir_path);
	if(list == NULL)
	{
		ASSERT(0);
	}
	
	_pvr_mgr_malloc(item_info, sizeof(REC_ENG_INFO), 1);

	if(TRUE == pvr_eng_is_our_file(dir_path, item_info) 
        && (item_info->old_item != PVR_REC_ITEM_NONE))
	{
		_pvr_list_add_item(list, dir_path, item_info);			
	}

	_pvr_mgr_free(item_info);
			
	return RET_SUCCESS;
	
}

RET_CODE pvr_mgr_add_extfile(char *dir_path)
{
    DIR *dir = NULL;
    F_Dirent item;
    char path[256];

    if(dir_path == NULL)
    {
        PDEBUG("pvr_mgr_add_extfile::PUSH VOD dir is NULL\n");
        return 0;
    }

    _pvr_mgr_add_file(dir_path);
    
    dir = (DIR *)_opendir(dir_path);
    if(dir == NULL) return 0;
    
    while(_readdir(dir, &item) == TRUE)
    {
        if (item.is_dir)
        {
            MEMSET(path,0,sizeof(path));
            strcpy(path,dir_path);
            strcat(path,"/");
            strcat(path,item.name);
            _pvr_mgr_add_file(path);
        }
    }

    _closedir(dir);
    return 1;
}

UINT32 pvr_mgr_set_write_read_cache_ratio(UINT32 ratio)
{
    return pvr_eng_set_write_read_cache_ratio(ratio);
}

UINT32 pvr_mgr_get_write_read_cache_ratio()
{
    return pvr_eng_get_write_read_cache_ratio();
}
